new function to get the *real* geometry position of a window, taken
authorTim Janik <timj@gtk.org>
Fri, 25 Sep 1998 23:04:32 +0000 (23:04 +0000)
committerTim Janik <timj@src.gnome.org>
Fri, 25 Sep 1998 23:04:32 +0000 (23:04 +0000)
Sat Sep 25 23:33:55 1998  Tim Janik  <timj@gtk.org>

        * gdk/gdkwindow.c (gdk_window_get_root_origin): new function to get
        the *real* geometry position of a window, taken possible window
        manager offsets into account.
        this has been succesfully tested with fvwm, fvwm-2, bowman, olwm,
        olvwm, twm, ctwm, mlvwm, windowmaker and enlightenment.
        it does fail though for amiwm which adds windows to a pseudo root
        window, and for icewm by a small offset because it defines the
        geometry position whithin its border.

        * gtk/testgtk.c: added "saved position" test to figure how
        gdk_window_get_root_origin() interacts with window managers (repopup
        this window to figure ;).

14 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gdk/gdk.h
gdk/gdkglobals.c
gdk/gdkwindow.c
gdk/x11/gdkglobals-x11.c
gdk/x11/gdkwindow-x11.c
gtk/testgtk.c
tests/testgtk.c

index 29731854160b7c8731c3eb3a94a63f51865ca87a..f4ecaad421960ff4b67a412bd7b59304b2c93b59 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+Sat Sep 25 23:33:55 1998  Tim Janik  <timj@gtk.org>
+
+       * gdk/gdkwindow.c (gdk_window_get_root_origin): new function to get
+       the *real* geometry position of a window, taken possible window
+       manager offsets into account.
+       this has been succesfully tested with fvwm, fvwm-2, bowman, olwm,
+       olvwm, twm, ctwm, mlvwm, windowmaker and enlightenment.
+       it does fail though for amiwm which adds windows to a pseudo root
+       window, and for icewm by a small offset because it defines the
+       geometry position whithin its border.
+
+       * gtk/testgtk.c: added "saved position" test to figure how
+       gdk_window_get_root_origin() interacts with window managers (repopup
+       this window to figure ;).
+
 Wed Sep 23 06:09:19 1998  Tim Janik  <timj@gtk.org>
 
        * configure.in: update to Gtk+ version 1.1.3, binary age 1,
index 29731854160b7c8731c3eb3a94a63f51865ca87a..f4ecaad421960ff4b67a412bd7b59304b2c93b59 100644 (file)
@@ -1,3 +1,18 @@
+Sat Sep 25 23:33:55 1998  Tim Janik  <timj@gtk.org>
+
+       * gdk/gdkwindow.c (gdk_window_get_root_origin): new function to get
+       the *real* geometry position of a window, taken possible window
+       manager offsets into account.
+       this has been succesfully tested with fvwm, fvwm-2, bowman, olwm,
+       olvwm, twm, ctwm, mlvwm, windowmaker and enlightenment.
+       it does fail though for amiwm which adds windows to a pseudo root
+       window, and for icewm by a small offset because it defines the
+       geometry position whithin its border.
+
+       * gtk/testgtk.c: added "saved position" test to figure how
+       gdk_window_get_root_origin() interacts with window managers (repopup
+       this window to figure ;).
+
 Wed Sep 23 06:09:19 1998  Tim Janik  <timj@gtk.org>
 
        * configure.in: update to Gtk+ version 1.1.3, binary age 1,
index 29731854160b7c8731c3eb3a94a63f51865ca87a..f4ecaad421960ff4b67a412bd7b59304b2c93b59 100644 (file)
@@ -1,3 +1,18 @@
+Sat Sep 25 23:33:55 1998  Tim Janik  <timj@gtk.org>
+
+       * gdk/gdkwindow.c (gdk_window_get_root_origin): new function to get
+       the *real* geometry position of a window, taken possible window
+       manager offsets into account.
+       this has been succesfully tested with fvwm, fvwm-2, bowman, olwm,
+       olvwm, twm, ctwm, mlvwm, windowmaker and enlightenment.
+       it does fail though for amiwm which adds windows to a pseudo root
+       window, and for icewm by a small offset because it defines the
+       geometry position whithin its border.
+
+       * gtk/testgtk.c: added "saved position" test to figure how
+       gdk_window_get_root_origin() interacts with window managers (repopup
+       this window to figure ;).
+
 Wed Sep 23 06:09:19 1998  Tim Janik  <timj@gtk.org>
 
        * configure.in: update to Gtk+ version 1.1.3, binary age 1,
index 29731854160b7c8731c3eb3a94a63f51865ca87a..f4ecaad421960ff4b67a412bd7b59304b2c93b59 100644 (file)
@@ -1,3 +1,18 @@
+Sat Sep 25 23:33:55 1998  Tim Janik  <timj@gtk.org>
+
+       * gdk/gdkwindow.c (gdk_window_get_root_origin): new function to get
+       the *real* geometry position of a window, taken possible window
+       manager offsets into account.
+       this has been succesfully tested with fvwm, fvwm-2, bowman, olwm,
+       olvwm, twm, ctwm, mlvwm, windowmaker and enlightenment.
+       it does fail though for amiwm which adds windows to a pseudo root
+       window, and for icewm by a small offset because it defines the
+       geometry position whithin its border.
+
+       * gtk/testgtk.c: added "saved position" test to figure how
+       gdk_window_get_root_origin() interacts with window managers (repopup
+       this window to figure ;).
+
 Wed Sep 23 06:09:19 1998  Tim Janik  <timj@gtk.org>
 
        * configure.in: update to Gtk+ version 1.1.3, binary age 1,
index 29731854160b7c8731c3eb3a94a63f51865ca87a..f4ecaad421960ff4b67a412bd7b59304b2c93b59 100644 (file)
@@ -1,3 +1,18 @@
+Sat Sep 25 23:33:55 1998  Tim Janik  <timj@gtk.org>
+
+       * gdk/gdkwindow.c (gdk_window_get_root_origin): new function to get
+       the *real* geometry position of a window, taken possible window
+       manager offsets into account.
+       this has been succesfully tested with fvwm, fvwm-2, bowman, olwm,
+       olvwm, twm, ctwm, mlvwm, windowmaker and enlightenment.
+       it does fail though for amiwm which adds windows to a pseudo root
+       window, and for icewm by a small offset because it defines the
+       geometry position whithin its border.
+
+       * gtk/testgtk.c: added "saved position" test to figure how
+       gdk_window_get_root_origin() interacts with window managers (repopup
+       this window to figure ;).
+
 Wed Sep 23 06:09:19 1998  Tim Janik  <timj@gtk.org>
 
        * configure.in: update to Gtk+ version 1.1.3, binary age 1,
index 29731854160b7c8731c3eb3a94a63f51865ca87a..f4ecaad421960ff4b67a412bd7b59304b2c93b59 100644 (file)
@@ -1,3 +1,18 @@
+Sat Sep 25 23:33:55 1998  Tim Janik  <timj@gtk.org>
+
+       * gdk/gdkwindow.c (gdk_window_get_root_origin): new function to get
+       the *real* geometry position of a window, taken possible window
+       manager offsets into account.
+       this has been succesfully tested with fvwm, fvwm-2, bowman, olwm,
+       olvwm, twm, ctwm, mlvwm, windowmaker and enlightenment.
+       it does fail though for amiwm which adds windows to a pseudo root
+       window, and for icewm by a small offset because it defines the
+       geometry position whithin its border.
+
+       * gtk/testgtk.c: added "saved position" test to figure how
+       gdk_window_get_root_origin() interacts with window managers (repopup
+       this window to figure ;).
+
 Wed Sep 23 06:09:19 1998  Tim Janik  <timj@gtk.org>
 
        * configure.in: update to Gtk+ version 1.1.3, binary age 1,
index 29731854160b7c8731c3eb3a94a63f51865ca87a..f4ecaad421960ff4b67a412bd7b59304b2c93b59 100644 (file)
@@ -1,3 +1,18 @@
+Sat Sep 25 23:33:55 1998  Tim Janik  <timj@gtk.org>
+
+       * gdk/gdkwindow.c (gdk_window_get_root_origin): new function to get
+       the *real* geometry position of a window, taken possible window
+       manager offsets into account.
+       this has been succesfully tested with fvwm, fvwm-2, bowman, olwm,
+       olvwm, twm, ctwm, mlvwm, windowmaker and enlightenment.
+       it does fail though for amiwm which adds windows to a pseudo root
+       window, and for icewm by a small offset because it defines the
+       geometry position whithin its border.
+
+       * gtk/testgtk.c: added "saved position" test to figure how
+       gdk_window_get_root_origin() interacts with window managers (repopup
+       this window to figure ;).
+
 Wed Sep 23 06:09:19 1998  Tim Janik  <timj@gtk.org>
 
        * configure.in: update to Gtk+ version 1.1.3, binary age 1,
index e8e29872c31a776bcae04edf54151aa52a5c7328..049e556a204d9dd4cee4c678d8310efc5ebf2625 100644 (file)
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -282,6 +282,9 @@ GdkWindowType gdk_window_get_type    (GdkWindow       *window);
 gint         gdk_window_get_origin      (GdkWindow       *window,
                                          gint            *x,
                                          gint            *y);
+void         gdk_window_get_root_origin (GdkWindow       *window,
+                                         gint            *x,
+                                         gint            *y);
 GdkWindow*    gdk_window_get_pointer    (GdkWindow       *window,
                                          gint            *x,
                                          gint            *y,
index bd8d537852ff2793e3957d1229f23c17f285ccea..d21be2f294cfb13f63452fb8a6e41fa9e095d02d 100644 (file)
@@ -29,7 +29,7 @@ Display          *gdk_display = NULL;
 gint              gdk_screen;
 Window            gdk_root_window;
 Window            gdk_leader_window;
-GdkWindowPrivate  gdk_root_parent;
+GdkWindowPrivate  gdk_root_parent = { { NULL, }, NULL, };
 Atom              gdk_wm_delete_window;
 Atom              gdk_wm_take_focus;
 Atom              gdk_wm_protocols;
index afbcdc4cc92e13f4e8d944794bf087cafa662cb5..7c2d9b099c69ee7979a51f73c3c123b5671e841c 100644 (file)
@@ -208,8 +208,8 @@ gdk_window_init (void)
                &x, &y, &width, &height, &border_width, &depth);
   XGetWindowAttributes (gdk_display, gdk_root_window, &xattributes);
 
-  gdk_root_parent.xdisplay = gdk_display;
   gdk_root_parent.xwindow = gdk_root_window;
+  gdk_root_parent.xdisplay = gdk_display;
   gdk_root_parent.window_type = GDK_WINDOW_ROOT;
   gdk_root_parent.window.user_data = NULL;
   gdk_root_parent.width = width;
@@ -1322,6 +1322,62 @@ gdk_window_get_origin (GdkWindow *window,
   return return_val;
 }
 
+void
+gdk_window_get_root_origin (GdkWindow *window,
+                           gint      *x,
+                           gint      *y)
+{
+  GdkWindowPrivate *private;
+  Window xwindow;
+  Window xparent;
+  Window root;
+  Window *children;
+  unsigned int nchildren;
+
+  g_return_if_fail (window != NULL);
+
+  private = (GdkWindowPrivate*) window;
+  if (x)
+    *x = 0;
+  if (y)
+    *y = 0;
+  if (private->destroyed)
+    return;
+      
+  while (private->parent && ((GdkWindowPrivate*) private->parent)->parent)
+    private = (GdkWindowPrivate*) private->parent;
+  if (private->destroyed)
+    return;
+
+  xparent = private->xwindow;
+  do
+    {
+      xwindow = xparent;
+      if (!XQueryTree (private->xdisplay, xwindow,
+                      &root, &xparent,
+                      &children, &nchildren))
+       return;
+
+      if (children)
+       XFree (children);
+    }
+  while (xparent != root);
+
+  if (xparent == root)
+    {
+      unsigned int ww, wh, wb, wd;
+      int wx, wy;
+
+      if (XGetGeometry (private->xdisplay, xwindow, &root, &wx, &wy, &ww, &wh, &wb, &wd))
+       {
+         if (x)
+           *x = wx;
+         if (y)
+           *y = wy;
+       }
+    }
+}
+
 GdkWindow*
 gdk_window_get_pointer (GdkWindow       *window,
                        gint            *x,
index bd8d537852ff2793e3957d1229f23c17f285ccea..d21be2f294cfb13f63452fb8a6e41fa9e095d02d 100644 (file)
@@ -29,7 +29,7 @@ Display          *gdk_display = NULL;
 gint              gdk_screen;
 Window            gdk_root_window;
 Window            gdk_leader_window;
-GdkWindowPrivate  gdk_root_parent;
+GdkWindowPrivate  gdk_root_parent = { { NULL, }, NULL, };
 Atom              gdk_wm_delete_window;
 Atom              gdk_wm_take_focus;
 Atom              gdk_wm_protocols;
index afbcdc4cc92e13f4e8d944794bf087cafa662cb5..7c2d9b099c69ee7979a51f73c3c123b5671e841c 100644 (file)
@@ -208,8 +208,8 @@ gdk_window_init (void)
                &x, &y, &width, &height, &border_width, &depth);
   XGetWindowAttributes (gdk_display, gdk_root_window, &xattributes);
 
-  gdk_root_parent.xdisplay = gdk_display;
   gdk_root_parent.xwindow = gdk_root_window;
+  gdk_root_parent.xdisplay = gdk_display;
   gdk_root_parent.window_type = GDK_WINDOW_ROOT;
   gdk_root_parent.window.user_data = NULL;
   gdk_root_parent.width = width;
@@ -1322,6 +1322,62 @@ gdk_window_get_origin (GdkWindow *window,
   return return_val;
 }
 
+void
+gdk_window_get_root_origin (GdkWindow *window,
+                           gint      *x,
+                           gint      *y)
+{
+  GdkWindowPrivate *private;
+  Window xwindow;
+  Window xparent;
+  Window root;
+  Window *children;
+  unsigned int nchildren;
+
+  g_return_if_fail (window != NULL);
+
+  private = (GdkWindowPrivate*) window;
+  if (x)
+    *x = 0;
+  if (y)
+    *y = 0;
+  if (private->destroyed)
+    return;
+      
+  while (private->parent && ((GdkWindowPrivate*) private->parent)->parent)
+    private = (GdkWindowPrivate*) private->parent;
+  if (private->destroyed)
+    return;
+
+  xparent = private->xwindow;
+  do
+    {
+      xwindow = xparent;
+      if (!XQueryTree (private->xdisplay, xwindow,
+                      &root, &xparent,
+                      &children, &nchildren))
+       return;
+
+      if (children)
+       XFree (children);
+    }
+  while (xparent != root);
+
+  if (xparent == root)
+    {
+      unsigned int ww, wh, wb, wd;
+      int wx, wy;
+
+      if (XGetGeometry (private->xdisplay, xwindow, &root, &wx, &wy, &ww, &wh, &wb, &wd))
+       {
+         if (x)
+           *x = wx;
+         if (y)
+           *y = wy;
+       }
+    }
+}
+
 GdkWindow*
 gdk_window_get_pointer (GdkWindow       *window,
                        gint            *x,
index f101c15a7ad61fa37f29d57e8a5a916ec1a0bcb3..1c8e9ed3765fa9291a78daaf488e93ca6f6f52a7 100644 (file)
@@ -1712,6 +1712,120 @@ create_reparent (void)
     gtk_widget_destroy (window);
 }
 
+/*
+ * Saved Position
+ */
+gint upositionx = 0;
+gint upositiony = 0;
+
+static gint
+uposition_configure (GtkWidget *window)
+{
+  GtkLabel *lx;
+  GtkLabel *ly;
+  gchar buffer[64];
+
+  lx = gtk_object_get_data (GTK_OBJECT (window), "x");
+  ly = gtk_object_get_data (GTK_OBJECT (window), "y");
+
+  gdk_window_get_root_origin (window->window, &upositionx, &upositiony);
+  sprintf (buffer, "%d", upositionx);
+  gtk_label_set (lx, buffer);
+  sprintf (buffer, "%d", upositiony);
+  gtk_label_set (ly, buffer);
+
+  return FALSE;
+}
+
+static void
+create_saved_position (void)
+{
+  static GtkWidget *window = NULL;
+
+  if (!window)
+    {
+      GtkWidget *hbox;
+      GtkWidget *main_vbox;
+      GtkWidget *vbox;
+      GtkWidget *x_label;
+      GtkWidget *y_label;
+      GtkWidget *button;
+      GtkWidget *label;
+      GtkWidget *any;
+
+      window = gtk_widget_new (GTK_TYPE_WINDOW,
+                              "type", GTK_WINDOW_TOPLEVEL,
+                              "signal::configure_event", uposition_configure, NULL,
+                              "x", upositionx,
+                              "y", upositiony,
+                              "title", "Saved Position",
+                              NULL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         GTK_SIGNAL_FUNC (gtk_widget_destroyed),
+                         &window);
+
+      main_vbox = gtk_vbox_new (FALSE, 5);
+      gtk_container_border_width (GTK_CONTAINER (main_vbox), 0);
+      gtk_container_add (GTK_CONTAINER (window), main_vbox);
+
+      vbox =
+       gtk_widget_new (gtk_vbox_get_type (),
+                       "GtkBox::homogeneous", FALSE,
+                       "GtkBox::spacing", 5,
+                       "GtkContainer::border_width", 10,
+                       "GtkWidget::parent", main_vbox,
+                       "GtkWidget::visible", TRUE,
+                       NULL);
+
+      hbox = gtk_hbox_new (FALSE, 0);
+      gtk_container_border_width (GTK_CONTAINER (hbox), 5);
+      gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
+
+      label = gtk_label_new ("X Origin : ");
+      gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+      gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
+
+      x_label = gtk_label_new ("");
+      gtk_box_pack_start (GTK_BOX (hbox), x_label, TRUE, TRUE, 0);
+      gtk_object_set_data (GTK_OBJECT (window), "x", x_label);
+
+      hbox = gtk_hbox_new (FALSE, 0);
+      gtk_container_border_width (GTK_CONTAINER (hbox), 5);
+      gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
+
+      label = gtk_label_new ("Y Origin : ");
+      gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+      gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
+
+      y_label = gtk_label_new ("");
+      gtk_box_pack_start (GTK_BOX (hbox), y_label, TRUE, TRUE, 0);
+      gtk_object_set_data (GTK_OBJECT (window), "y", y_label);
+
+      any =
+       gtk_widget_new (gtk_hseparator_get_type (),
+                       "GtkWidget::visible", TRUE,
+                       NULL);
+      gtk_box_pack_start (GTK_BOX (main_vbox), any, FALSE, TRUE, 0);
+
+      hbox = gtk_hbox_new (FALSE, 0);
+      gtk_container_border_width (GTK_CONTAINER (hbox), 10);
+      gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, TRUE, 0);
+
+      button = gtk_button_new_with_label ("Close");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                GTK_SIGNAL_FUNC (gtk_widget_destroy),
+                                GTK_OBJECT (window));
+      gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_widget_grab_default (button);
+      
+      gtk_widget_show_all (window);
+    }
+  else
+    gtk_widget_destroy (window);
+}
+
 /*
  * GtkPixmap
  */
@@ -7621,6 +7735,7 @@ create_main_window (void)
       { "rc file", create_rc_file },
       { "reparent", create_reparent },
       { "rulers", create_rulers },
+      { "saved position", create_saved_position },
       { "scrolled windows", create_scrolled_windows },
       { "shapes", create_shapes },
       { "spinbutton", create_spins },
index f101c15a7ad61fa37f29d57e8a5a916ec1a0bcb3..1c8e9ed3765fa9291a78daaf488e93ca6f6f52a7 100644 (file)
@@ -1712,6 +1712,120 @@ create_reparent (void)
     gtk_widget_destroy (window);
 }
 
+/*
+ * Saved Position
+ */
+gint upositionx = 0;
+gint upositiony = 0;
+
+static gint
+uposition_configure (GtkWidget *window)
+{
+  GtkLabel *lx;
+  GtkLabel *ly;
+  gchar buffer[64];
+
+  lx = gtk_object_get_data (GTK_OBJECT (window), "x");
+  ly = gtk_object_get_data (GTK_OBJECT (window), "y");
+
+  gdk_window_get_root_origin (window->window, &upositionx, &upositiony);
+  sprintf (buffer, "%d", upositionx);
+  gtk_label_set (lx, buffer);
+  sprintf (buffer, "%d", upositiony);
+  gtk_label_set (ly, buffer);
+
+  return FALSE;
+}
+
+static void
+create_saved_position (void)
+{
+  static GtkWidget *window = NULL;
+
+  if (!window)
+    {
+      GtkWidget *hbox;
+      GtkWidget *main_vbox;
+      GtkWidget *vbox;
+      GtkWidget *x_label;
+      GtkWidget *y_label;
+      GtkWidget *button;
+      GtkWidget *label;
+      GtkWidget *any;
+
+      window = gtk_widget_new (GTK_TYPE_WINDOW,
+                              "type", GTK_WINDOW_TOPLEVEL,
+                              "signal::configure_event", uposition_configure, NULL,
+                              "x", upositionx,
+                              "y", upositiony,
+                              "title", "Saved Position",
+                              NULL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         GTK_SIGNAL_FUNC (gtk_widget_destroyed),
+                         &window);
+
+      main_vbox = gtk_vbox_new (FALSE, 5);
+      gtk_container_border_width (GTK_CONTAINER (main_vbox), 0);
+      gtk_container_add (GTK_CONTAINER (window), main_vbox);
+
+      vbox =
+       gtk_widget_new (gtk_vbox_get_type (),
+                       "GtkBox::homogeneous", FALSE,
+                       "GtkBox::spacing", 5,
+                       "GtkContainer::border_width", 10,
+                       "GtkWidget::parent", main_vbox,
+                       "GtkWidget::visible", TRUE,
+                       NULL);
+
+      hbox = gtk_hbox_new (FALSE, 0);
+      gtk_container_border_width (GTK_CONTAINER (hbox), 5);
+      gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
+
+      label = gtk_label_new ("X Origin : ");
+      gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+      gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
+
+      x_label = gtk_label_new ("");
+      gtk_box_pack_start (GTK_BOX (hbox), x_label, TRUE, TRUE, 0);
+      gtk_object_set_data (GTK_OBJECT (window), "x", x_label);
+
+      hbox = gtk_hbox_new (FALSE, 0);
+      gtk_container_border_width (GTK_CONTAINER (hbox), 5);
+      gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
+
+      label = gtk_label_new ("Y Origin : ");
+      gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+      gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
+
+      y_label = gtk_label_new ("");
+      gtk_box_pack_start (GTK_BOX (hbox), y_label, TRUE, TRUE, 0);
+      gtk_object_set_data (GTK_OBJECT (window), "y", y_label);
+
+      any =
+       gtk_widget_new (gtk_hseparator_get_type (),
+                       "GtkWidget::visible", TRUE,
+                       NULL);
+      gtk_box_pack_start (GTK_BOX (main_vbox), any, FALSE, TRUE, 0);
+
+      hbox = gtk_hbox_new (FALSE, 0);
+      gtk_container_border_width (GTK_CONTAINER (hbox), 10);
+      gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, TRUE, 0);
+
+      button = gtk_button_new_with_label ("Close");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                GTK_SIGNAL_FUNC (gtk_widget_destroy),
+                                GTK_OBJECT (window));
+      gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_widget_grab_default (button);
+      
+      gtk_widget_show_all (window);
+    }
+  else
+    gtk_widget_destroy (window);
+}
+
 /*
  * GtkPixmap
  */
@@ -7621,6 +7735,7 @@ create_main_window (void)
       { "rc file", create_rc_file },
       { "reparent", create_reparent },
       { "rulers", create_rulers },
+      { "saved position", create_saved_position },
       { "scrolled windows", create_scrolled_windows },
       { "shapes", create_shapes },
       { "spinbutton", create_spins },